package com.lazydong.apiforward.client.framework.util;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarClassScanner {

    /**
     * Finds all classes within a given package in a specified JAR file.
     *
     * @param jarPath The path to the JAR file.
     * @param packageName The base package name to scan.
     * @return A list of classes found in the specified package and subpackages.
     */
    public static List<Class<?>> findClassesInJar(String jarPath, String packageName) {
        String jarFilePath = getJarPath(jarPath);
        List<Class<?>> classes = new ArrayList<>();
        try (JarFile jarFile = new JarFile(new File(jarFilePath))) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String name = entry.getName();
                if (name.startsWith(packageName.replace('.', '/')) && name.endsWith(".class")) {
                    String className = name.substring(0, name.length() - 6).replace('/', '.');
                    classes.add(loadClass(className, jarFilePath));
                }
            }
        } catch (IOException e) {
            System.err.println("Error scanning JAR file: " + jarFilePath);
            e.printStackTrace();
        }
        return classes;
    }

    private static String getJarPath(String path) {
        // 有可能是内存里面的jar，不是外部的jar
        String[] split = path.split(".jar!");
        String string = split[0];
        string = string.replace("file:/", "");
        return string + ".jar";
    }

    private static Class<?> loadClass(String className, String jarFilePath) {
        try (URLClassLoader cl = new URLClassLoader(new URL[]{new File(jarFilePath).toURI().toURL()})) {
            return cl.loadClass(className);
        } catch (Exception e) {
            System.err.println("Error loading class: " + className);
            e.printStackTrace();
            return null;
        }
    }
}